package cn.yunhe.intercept;

import cn.yunhe.util.RedisUtil;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MethodCacheInterceptor implements MethodInterceptor {
    private Logger logger = LoggerFactory.getLogger(MethodCacheInterceptor.class);
    private RedisUtil redisUtil;
    private Long defaultCacheExpireTime;    //缓存默认的过期时间


    /**
     * 初始化读取不需要加入缓存的类名和方法名
     */
    public MethodCacheInterceptor() {
        try {
            //加载过期时间设置
            defaultCacheExpireTime = 3600L;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object value = null;

        String targetName = invocation.getThis().getClass().getName();
        String methodName = invocation.getMethod().getName();

        Object[] arguments = invocation.getArguments();
        final String key = getCacheKey(targetName, methodName, arguments);
        logger.debug("redisKey:" + key);

        try {
            //判断是否有缓存
            if (redisUtil.exists(key)) {
                return redisUtil.get(key);
            }
            //写入缓存
            value = invocation.proceed();
            if (value != null) {
                final String tkey = key;
                final Object tvalue = value;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                       redisUtil.set(tkey, tvalue, defaultCacheExpireTime);
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (value == null) {
                return invocation.proceed();
            }
        }

        return value;
    }


    /**
     * 创建缓存key
     *
     * @param targetName
     * @param methodName
     * @param arguments
     * @return
     */
    private String getCacheKey(String targetName, String methodName, Object[] arguments) {
        StringBuffer sbu = new StringBuffer();

        sbu.append(targetName).append("_").append(methodName);
        if ((arguments != null) && (arguments.length != 0)) {
            for (int i = 0; i < arguments.length; i++) {
                sbu.append("_").append(arguments[i]);
            }
        }
        return sbu.toString();
    }


    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }
}
